﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using YookingBizWQW.Class.Public;
using YookingDBNormal.Class;
using YookingFileIO.Class;
using YookingKitBox.Class.Public;
using YookingSvrDBCall.Class.DBLogic;
using YookingSvrDBCall.Class.DBPub;

namespace YookingBizWQW.Class.Credit.pub
{
    public class clsMbrUpdate
    {
        //注释：王庆文 2020年04月16日=====================================================================
        //用户通过APP进行充值操作，根据相应的充值金额，将会员升级到对应的级别。
        //升级方式MbrUpdWay：
        //00=用户注册升级，01=直接充值升级，02=充值补差价升级，
        //03=绑卡达到规定人数升级，04=平台管理员操作升级
        public string RechargeUpdateMemberLevel(string strB64RequestData)
        {
            //先进行解密，然后在进行中文解码，最后得到明文的请求数据
            string strRequestData = clsHandleData.DeUrlRequest(strB64RequestData);

            #region 将strRequestData包含的各种参数一一解析出来

            string strUnitCode = "000";   //平台编码
            string strMID = "00000000";   //会员ID
            string strMemberLevel = "00"; //会员将要升级的目标级别
            string strMbrUpdWay = "01";   //升级方式

            //这些参数用★分隔开，客户端与服务器端要一致
            string[] strArray = strRequestData.Split('★');
            if (strArray.Length >= 4)
            {
                strUnitCode = strArray[0];
                strMID = strArray[1];
                strMemberLevel = strArray[2];
                strMbrUpdWay = strArray[3];
            }

            #endregion

            object objResult = ChangeMemberLevel(strUnitCode, strMID,strMemberLevel, strMbrUpdWay);

            return objResult.ToString(); //返回受影响的记录行数
        }

        //注释：王庆文 2020年04月16日=======================================================================
        //当会员的下级绑卡人数达到某个值，系统会自动将该会员的级别升级成与人数相对应的等级。
        public string BindUpdateMemberLevel()
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT UNITCODE,MID,MEMBERLEVEL,VIRTBINDCOUNT FROM XYK_MEMBER_INFO ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "SYS_CANCELDATETIME"));

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            DataSet dsMbr = myDB.YookingExecuteDataSet("Data", sbQuerySQL.ToString());

            int iOlapCount = 0; //被分析处理过的会员数
            int iMbrCount = 0;  //数据库中的会员总数
            if (dsMbr != null && dsMbr.Tables.Count > 0 && dsMbr.Tables[0].Rows.Count > 0)
            {
                DataTable dtMbr = dsMbr.Tables[0];

                iMbrCount = dtMbr.Rows.Count;
                foreach (DataRow drRow in dtMbr.Rows)
                {
                    string strUnitCode = drRow["UNITCODE"].ToString();
                    string strMID = drRow["MID"].ToString(); //会员ID
                    string strMemberLevel = drRow["MEMBERLEVEL"].ToString();

                    //虚拟绑卡总人数
                    string strVirtBindCount = drRow["VIRTBINDCOUNT"].ToString();
                    int iVirtBindCount = Convert.ToInt32(strVirtBindCount);

                    //计算当前会员的全部下属一级会员的实际绑卡的总人数
                    int iRealBindCount = GetALevelMemberRealBindCount(strUnitCode, strMID);

                    //全部绑卡人数 = 实际绑卡人数 + 虚拟绑卡人数
                    int iAllBindCount = iRealBindCount + iVirtBindCount;

                    //根据全部绑卡人数的值，得到这个人数对应的会员级别代码
                    DataSet dsCode = GetNewMemberLevelCode(strUnitCode, iAllBindCount);
                    if (dsCode != null && dsCode.Tables.Count > 0 && dsCode.Tables[0].Rows.Count > 0)
                    {
                        string strNewLevelCode = dsCode.Tables[0].Rows[0]["LEVELCODE"].ToString();

                        //03=绑卡达到规定人数升级，04=平台管理员操作升级
                        if (strMemberLevel.CompareTo(strNewLevelCode) < 0)
                        {
                            //将会员级别升级成跟绑卡人数相对应的等级
                            ManageUpdateMemberLevel(strUnitCode, strMID, strNewLevelCode, "03");

                            iOlapCount = iOlapCount + 1; //实际处理了几个会员的绑卡业务
                        }
                    }
                }
            }

            return "{\"result\":\"【绑卡升级情况：" + iOlapCount + "/" + iMbrCount + "】\"}"; 
        }

        //注释：王庆文 2020年05月27日=====================================================================
        //管理员在PC端通过浏览器客户端手动操作，将会员升级到对应的级别。
        //升级方式MbrUpdWay：00=用户注册升级，01=直接充值升级，02=充值补差价升级，
        //                   03=绑卡达到规定人数升级，04=平台管理员操作升级
        public string ManuallyUpdateMemberLevel(string strB64RequestData)
        {
            //先进行解密，然后在进行中文解码，最后得到明文的请求数据
            string strRequestData = clsHandleData.DeUrlRequest(strB64RequestData);

            #region 将strRequestData包含的各种参数一一解析出来

            string strUnitCode = "000";   //平台编码
            string strMID = "00000000";   //会员ID
            string strMemberLevel = "00"; //会员将要升级的目标级别

            //这些参数用★分隔开，客户端与服务器端要一致
            string[] strArray = strRequestData.Split('★');
            if (strArray.Length >= 3)
            {
                strUnitCode = strArray[0];
                strMID = strArray[1];
                strMemberLevel = strArray[2];
            }

            #endregion

            //管理员手动升级会员级别，虚拟绑卡人数将会发生变化，但是不会给予上级、上上级奖励
            string strUpdResult = ManageUpdateMemberLevel(strUnitCode, strMID, strMemberLevel, "04"); 

            return strUpdResult; //返回升级处理结果
        }

        //注释：王庆文 2020年04月16日=======================================================================
        //03=绑卡达到规定人数升级，04=平台管理员操作升级
        //升级方式为：03 和 04 时，需要为被升级的会员的【会员充值情况汇总表(XYK_RechargePool)】
        //中添加一条虚拟充值记录，以使得下级绑卡会员总数与对应的充值资金数之间达到一一对应和系统平衡。
        public string ManageUpdateMemberLevel(string strUnitCode, string strMID,
                                              string strMemberLevel, string strMbrUpdWay)
        {
            string strRtData = "no data"; //最终的写库结果

            //先将会员升级到指定级别strMemberLevel
            object objResult = ChangeMemberLevel(strUnitCode, strMID, strMemberLevel, strMbrUpdWay);

            //如果升级成功，则为该会员添加虚拟充值记录
            if (Convert.ToInt32(objResult) > 0)
            {
                //查询会员级别字典表，获知达到该级别需要充值多少钱
                double dLevelAmount = GetMbrLevelRechargeAmount(strUnitCode, strMemberLevel);

                //查询会员已经充过值的金额总数
                double dRechargeSum = GetMemberRhgPoolSum(strUnitCode, strMID);

                //如果已经充值的金额总数不够该级
                //别应支付的金额，则自动为该会员虚拟充值
                if (dRechargeSum < dLevelAmount)
                {
                    //待充值的金额=指定级别要求的额度 - 该会员已经充值的总额
                    double dPayAmount = dLevelAmount - dRechargeSum;

                    string strCurTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

                    Random rd = new Random(); //随机数实例
                    int iRandom = rd.Next(1000, 9999); //生成四位随机数
                    string strCurValue = DateTime.Now.ToString("yyyyMMddHHmmss");
                    string strOrderID = "XNCZ" + strCurValue + iRandom; //订单号

                    #region 生成将要写入充值汇总表中的json数据数组

                    string strJsonArray = "[{"; //封装成json格式的大文本数组
                    strJsonArray += "\"UnitCode\":\"" + strUnitCode + "\",";      //平台编码
                    strJsonArray += "\"PayPerson\":\"" + strMID + "\",";          //充值人员
                    strJsonArray += "\"PayTime\":\"" + strCurTime + "\",";        //充值时间
                    strJsonArray += "\"PayMode\":\"99\","; //充值方式,01现金、02支付宝、03微信、04信用卡、05银行卡、06对公转账、99其它方式
                    strJsonArray += "\"PayAmount\":\"" + dPayAmount + "\",";      //充值金额
                    strJsonArray += "\"OrderID\":\"" + strOrderID + "\",";        //订单号码
                    strJsonArray += "\"IsSuccess\":\"1\","; //是否支付成功：0=充值失败，1=充值成功
                    strJsonArray += "\"PartnerID\":\"" + strUnitCode + "\",";     //收款商家ID
                    strJsonArray += "\"AppID\":\"" + strUnitCode + "\",";         //应用APPID
                    strJsonArray += "\"WxOpenID\":\"\",";                         //微信用户标识
                    strJsonArray += "\"WxTradeState\":\"\",";                     //微信交易状态
                    strJsonArray += "\"WxOrderID\":\"\",";                        //微信支付订单号
                    strJsonArray += "\"WxTimeEnd\":\"\",";                        //微信支付完成时间
                    strJsonArray += "\"AccountBank\":\"\",";                      //开户银行
                    strJsonArray += "\"AccountName\":\"\",";                      //银行户名
                    strJsonArray += "\"AccountNumber\":\"\",";                    //银行账号
                    strJsonArray += "\"MbrUpdLevel\":\"" + strMemberLevel + "\",";//升级级别
                    strJsonArray += "\"MbrUpdWay\":\"" + strMbrUpdWay + "\",";    //升级方式
                    strJsonArray += "\"OtherMemo\":\"平台为该会员做的虚拟充值\""; //其他备注
                    strJsonArray += "}]";

                    #endregion

                    DataSet dsData = clsJConvert.JArryToDataSet(strJsonArray); //将Json数组转成DataSet

                    clsWriteDB myWrite = new clsWriteDB(); //先判断数据是否存在，根据判断结果自动执行insert或者update
                    string strKeyColSet = "UnitCode,PayPerson,PayMode,PayAmount";
                    strRtData = myWrite.WriteDBNormal_UseSYSCol("Data", "XYK_RECHARGEPOOL", strKeyColSet, "02120119901", dsData);
                }
            }

            return strRtData; //数据库操作的最终结果
        }

        #region 会员升级操作用到的公共函数

        //注释：王庆文 2020年04月16日=====================================================================
        //更新指定MID的会员信息，修改会员级别、升级方式、绑卡会员数量等信息。
        //升级方式MbrUpdWay：
        //00=用户注册升级，01=直接充值升级，02=充值补差价升级，
        //03=绑卡达到规定人数升级，04=平台管理员操作升级
        public object ChangeMemberLevel(string strUnitCode, string strMID, 
                                        string strMemberLevel, string strMbrUpdWay)
        {
            string strCurTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            //计算下级实际绑卡的会员总数、
            //以及升级到strMemberLevel级最少需要多少个下级绑卡会员
            int iRealBindCount = GetALevelMemberRealBindCount(strUnitCode, strMID);
            int iMinChildCount = GetMinChildCountValue(strUnitCode, strMemberLevel);

            //充值、管理员操作等方式导致会员升级，则实际绑卡数量不够的，
            //通过填写虚拟绑卡人数来凑齐会员升级需要的人数，补个差值。
            int iVirtBindCount = iMinChildCount - iRealBindCount;

            #region 生成update记录的SQL语句

            StringBuilder sbUpdateSQL = new StringBuilder();
            sbUpdateSQL.AppendLine(" UPDATE XYK_MEMBER_INFO SET ");
            sbUpdateSQL.AppendLine("  MEMBERLEVEL='" + strMemberLevel + "', ");
            sbUpdateSQL.AppendLine("  MBRUPDTIME='" + strCurTime + "', ");
            sbUpdateSQL.AppendLine("  MBRUPDWAY='" + strMbrUpdWay + "', ");
            sbUpdateSQL.AppendLine("  REALBINDCOUNT='" + iRealBindCount + "', ");
            sbUpdateSQL.AppendLine("  VIRTBINDCOUNT='" + iVirtBindCount + "' ");
            sbUpdateSQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "SYS_CANCELDATETIME"));
            sbUpdateSQL.AppendLine("  AND UNITCODE='" + strUnitCode + "' ");
            sbUpdateSQL.AppendLine("  AND MID='" + strMID + "' ");

            #endregion

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbUpdateSQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            object objResult = myDB.YookingExecuteNonQuery("Data", sbUpdateSQL.ToString());

            //如果升级成功，则为该会员的上级、上上级支付升级奖励
            if (Convert.ToInt32(objResult) > 0)
            {   
                clsMbrReward myPay = new clsMbrReward(); //自己的上级会员、上上级会员得到升级奖励
                myPay.CommitMbrUpdateRewardData_A(strUnitCode, strMID, strMemberLevel, strMbrUpdWay);
                myPay.CommitMbrUpdateRewardData_B(strUnitCode, strMID, strMemberLevel, strMbrUpdWay);
            }

            return objResult; //本次执行SQL受影响的记录行数
        }

        //注释：王庆文 2020年04月16日=====================================================================
        //根据全部绑卡人数的值，得到这个人数对应的会员级别代码
        private DataSet GetNewMemberLevelCode(string strUnitCode, int iAllBindCount)
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT LEVELCODE FROM XYK_MEMBER_LEVEL T ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "SYS_CANCELDATETIME"));
            sbQuerySQL.AppendLine("  AND T.UNITCODE = '" + strUnitCode + "' ");
            sbQuerySQL.AppendLine("  AND T.MINCHILDCOUNT <= '" + iAllBindCount + "' ");
            sbQuerySQL.AppendLine("  AND T.MAXCHILDCOUNT >= '" + iAllBindCount + "' ");

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbQuerySQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            return myDB.YookingExecuteDataSet("Data", sbQuerySQL.ToString());
        }

        //注释：王庆文 2020年04月16日=====================================================================
        //计算当前会员的全部下属一级会员的实际绑卡的总人数
        private int GetALevelMemberRealBindCount(string strUnitCode, string strMID)
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT COUNT(1) FROM XYK_MEMBER_INFO T ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "T.SYS_CANCELDATETIME"));
            sbQuerySQL.AppendLine("   AND T.UNITCODE = '" + strUnitCode + "' ");
            sbQuerySQL.AppendLine("   AND T.ISBINDCARD = '1' "); //1=已绑卡，0=未绑卡
            sbQuerySQL.AppendLine("   AND T.PID = '" + strMID + "' ");

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbQuerySQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            object objCount = myDB.YookingGetDataScalar("Data", sbQuerySQL.ToString());

            return Convert.ToInt32(objCount); //得到实际绑卡的总人数
        }

        //注释：王庆文 2020年04月16日=====================================================================
        //查询“会员级别信息字典表”，判断达到指定级别最少需要多少个下级绑卡会员
        private int GetMinChildCountValue(string strUnitCode, string strLevelCode)
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT MINCHILDCOUNT FROM XYK_MEMBER_LEVEL T ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "T.SYS_CANCELDATETIME"));
            sbQuerySQL.AppendLine("   AND T.UNITCODE = '" + strUnitCode + "' ");
            sbQuerySQL.AppendLine("   AND T.LEVELCODE = '" + strLevelCode + "' ");

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbQuerySQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            object objValue = myDB.YookingGetDataScalar("Data", sbQuerySQL.ToString());

            return Convert.ToInt32(objValue); //得到下级绑卡会员数量的最小值
        }

        //注释：王庆文 2020年04月16日=====================================================================
        //查询“会员级别信息字典表”，判断达到指定级别最少需要充值多少钱
        private double GetMbrLevelRechargeAmount(string strUnitCode, string strLevelCode)
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT FEEAMOUNT FROM XYK_MEMBER_LEVEL T ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "T.SYS_CANCELDATETIME"));
            sbQuerySQL.AppendLine("   AND T.UNITCODE = '" + strUnitCode + "' ");
            sbQuerySQL.AppendLine("   AND T.LEVELCODE = '" + strLevelCode + "' ");

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbQuerySQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            object objAmount = myDB.YookingGetDataScalar("Data", sbQuerySQL.ToString());

            return Convert.ToDouble(objAmount); //得到需要充值的金额数
        }

        //注释：王庆文 2020年04月16日============================================================================
        //查询指定会员充值的总金额，包括微信、支付宝充值，以及绑卡自动升级，或管理员操作升级的全部金额数总和
        private double GetMemberRhgPoolSum(string strUnitCode, string strMID)
        {
            StringBuilder sbQuerySQL = new StringBuilder();
            sbQuerySQL.AppendLine(" SELECT SUM(PAYAMOUNT) FROM XYK_RECHARGEPOOL T ");
            sbQuerySQL.AppendLine(" WHERE " + clsSQLSyntax.IsNullSQL("Data", "T.SYS_CANCELDATETIME"));
            sbQuerySQL.AppendLine("   AND T.UNITCODE = '" + strUnitCode + "' ");
            sbQuerySQL.AppendLine("   AND T.PAYPERSON = '" + strMID + "' ");

            //clsRWFile myLog = new clsRWFile(); //将待执行的SQL语句记录下来
            //myLog.WriteInfoToTxtFile("SysLog", "wqw.txt", sbQuerySQL.ToString(),false);

            clsDbSQLLogic myDB = new clsDbSQLLogic(); //实例化数据库操作类
            object objRhgSum = myDB.YookingGetDataScalar("Data", sbQuerySQL.ToString());

            return Convert.ToDouble(objRhgSum); //得到会员充值的总金额数
        }

        #endregion




    }
}
